/** Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 */
package redis.clients.jedis;

import java.nio.charset.StandardCharsets;
import redis.clients.jedis.args.Rawable;
import redis.clients.jedis.commands.ProtocolCommand;

/**
 * Redis protocol utilities and command definitions.
 *
 * <p>This class provides compatibility with original Jedis Protocol class, containing essential
 * constants and command definitions for Redis protocol operations.
 */
public class Protocol {

    /** Default Redis host */
    public static final String DEFAULT_HOST = "localhost";

    /** Default Redis port */
    public static final int DEFAULT_PORT = 6379;

    /** Default database index */
    public static final int DEFAULT_DATABASE = 0;

    /** Default timeout in milliseconds */
    public static final int DEFAULT_TIMEOUT = 2000;

    /**
     * Redis protocol commands enum.
     *
     * <p><b>Compatibility Note:</b> This includes all commands used by redis-jdbc-driver and other
     * compatibility layer consumers.
     */
    public enum Command implements ProtocolCommand {
        // Basic commands
        PING,
        AUTH,
        SET,
        GET,
        GETDEL,
        GETEX,
        EXISTS,
        DEL,
        UNLINK,
        TYPE,
        FLUSHDB,
        FLUSHALL,
        MOVE,
        KEYS,
        RANDOMKEY,
        RENAME,
        RENAMENX,
        DUMP,
        RESTORE,
        DBSIZE,
        SELECT,
        SWAPDB,
        MIGRATE,
        ECHO,

        // Key expiration
        EXPIRE,
        EXPIREAT,
        EXPIRETIME,
        PEXPIRE,
        PEXPIREAT,
        PEXPIRETIME,
        TTL,
        PTTL,

        // Transaction commands
        MULTI,
        DISCARD,
        EXEC,
        WATCH,
        UNWATCH,

        // String commands
        GETSET,
        MGET,
        SETNX,
        SETEX,
        PSETEX,
        MSET,
        MSETNX,
        DECR,
        DECRBY,
        INCR,
        INCRBY,
        INCRBYFLOAT,
        STRLEN,
        APPEND,
        SUBSTR,

        // Bit operations
        SETBIT,
        GETBIT,
        BITPOS,
        SETRANGE,
        GETRANGE,
        BITCOUNT,
        BITOP,
        BITFIELD,
        BITFIELD_RO,

        // Hash commands
        HSET,
        HGET,
        HSETNX,
        HMSET,
        HMGET,
        HINCRBY,
        HEXISTS,
        HDEL,
        HLEN,
        HKEYS,
        HVALS,
        HGETALL,
        HSTRLEN,
        HRANDFIELD,
        HINCRBYFLOAT,
        HSCAN,

        // List commands
        RPUSH,
        LPUSH,
        LLEN,
        LRANGE,
        LTRIM,
        LINDEX,
        LSET,
        LREM,
        LPOP,
        RPOP,
        BLPOP,
        BRPOP,
        LINSERT,
        LPOS,
        RPOPLPUSH,
        BRPOPLPUSH,
        BLMOVE,
        LMOVE,
        LMPOP,
        BLMPOP,
        LPUSHX,
        RPUSHX,

        // Set commands
        SADD,
        SMEMBERS,
        SREM,
        SPOP,
        SMOVE,
        SCARD,
        SRANDMEMBER,
        SINTER,
        SINTERSTORE,
        SUNION,
        SUNIONSTORE,
        SDIFF,
        SDIFFSTORE,
        SISMEMBER,
        SMISMEMBER,
        SINTERCARD,
        SSCAN,

        // Sorted Set commands
        ZADD,
        ZDIFF,
        ZDIFFSTORE,
        ZRANGE,
        ZREM,
        ZINCRBY,
        ZRANK,
        ZREVRANK,
        ZREVRANGE,
        ZRANDMEMBER,
        ZCARD,
        ZSCORE,
        ZPOPMAX,
        ZPOPMIN,
        ZCOUNT,
        ZUNION,
        ZUNIONSTORE,
        ZINTER,
        ZINTERSTORE,
        ZRANGEBYSCORE,
        ZREVRANGEBYSCORE,
        ZREMRANGEBYRANK,
        ZREMRANGEBYSCORE,
        ZLEXCOUNT,
        ZRANGEBYLEX,
        ZREVRANGEBYLEX,
        ZREMRANGEBYLEX,
        ZMSCORE,
        ZINTERCARD,
        ZMPOP,
        BZMPOP,
        BZPOPMIN,
        BZPOPMAX,
        ZSCAN,

        // Geo commands
        GEOADD,
        GEODIST,
        GEOHASH,
        GEOPOS,
        GEORADIUS,
        GEORADIUS_RO,
        GEOSEARCH,
        GEOSEARCHSTORE,
        GEORADIUSBYMEMBER,
        GEORADIUSBYMEMBER_RO,

        // HyperLogLog commands
        PFADD,
        PFCOUNT,
        PFMERGE,

        // Stream commands
        XADD,
        XLEN,
        XDEL,
        XTRIM,
        XRANGE,
        XREVRANGE,
        XREAD,
        XACK,
        XGROUP,
        XREADGROUP,
        XPENDING,
        XCLAIM,
        XAUTOCLAIM,
        XINFO,

        // Script commands
        EVAL,
        EVALSHA,
        SCRIPT,
        EVAL_RO,
        EVALSHA_RO,
        FUNCTION,
        FCALL,
        FCALL_RO,

        // Pub/Sub commands
        SUBSCRIBE,
        UNSUBSCRIBE,
        PSUBSCRIBE,
        PUNSUBSCRIBE,
        PUBLISH,
        PUBSUB,

        // Server commands
        SAVE,
        BGSAVE,
        BGREWRITEAOF,
        LASTSAVE,
        PERSIST,
        ROLE,
        SLOWLOG,
        OBJECT,
        CLIENT,
        TIME,
        SCAN,
        WAIT,
        CLUSTER,
        READONLY,
        READWRITE,
        SLAVEOF,
        REPLICAOF,
        COPY,
        SENTINEL,
        MODULE,
        ACL,
        TOUCH,
        MEMORY,
        LOLWUT,
        COMMAND,
        RESET,
        LATENCY,
        WAITAOF,

        // Additional commands from redis-jdbc-driver
        ADD,
        ADDNX,
        AGGREGATE,
        ALIASADD,
        ALIASDEL,
        ALIASUPDATE,
        ALTER,
        ARRAPPEND,
        ARRINDEX,
        ARRINSERT,
        ARRLEN,
        ARRPOP,
        ARRTRIM,
        BYRANK,
        BYREVRANK,
        CARD,
        CDF,
        CLEAR,
        CONFIG,
        COUNT,
        CREATE,
        CREATERULE,
        CURSOR,
        DEBUG,
        DELETERULE,
        DICTADD,
        DICTDEL,
        DICTDUMP,
        DROPINDEX,
        EXPLAIN,
        EXPLAINCLI,
        INITBYDIM,
        INITBYPROB,
        INSERT,
        INSERTNX,
        INFO,
        LIST,
        LOADCHUNK,
        MADD,
        MAX,
        MERGE,
        MEXISTS,
        MIN,
        MONITOR,
        MRANGE,
        MREVRANGE,
        NUMINCRBY,
        OBJKEYS,
        OBJLEN,
        PROFILE,
        QUANTILE,
        QUERY,
        QUERYINDEX,
        RANGE,
        RANK,
        RESERVE,
        RESP,
        REVRANGE,
        REVRANK,
        SCANDUMP,
        SEARCH,
        SHUTDOWN,
        SORT,
        SORT_RO,
        SPELLCHECK,
        STRAPPEND,
        SUGADD,
        SUGDEL,
        SUGGET,
        SUGLEN,
        SYNDUMP,
        SYNUPDATE,
        TAGVALS,
        TOGGLE,
        TRIMMED_MEAN,
        _LIST,
        LCS;

        private final byte[] raw;

        Command() {
            raw = name().getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public byte[] getRaw() {
            return raw.clone(); // ✅ Return defensive copy to prevent external modification
        }
    }

    /** Redis protocol keywords enum based on original Jedis Protocol.Keyword. */
    public enum Keyword implements Rawable {
        AGGREGATE,
        ALPHA,
        BY,
        GET,
        LIMIT,
        NO,
        NOSORT,
        ONE,
        SET,
        STORE,
        WEIGHTS,
        WITHSCORE,
        WITHSCORES,
        RESETSTAT,
        REWRITE,
        RESET,
        FLUSH,
        EXISTS,
        LOAD,
        LEN,
        HELP,
        SCHEDULE,
        MATCH,
        COUNT,
        TYPE,
        KEYS,
        REFCOUNT,
        ENCODING,
        IDLETIME,
        FREQ,
        REPLACE,
        GETNAME,
        SETNAME,
        SETINFO,
        LIST,
        ID,
        KILL,
        PERSIST,
        STREAMS,
        CREATE,
        MKSTREAM,
        SETID,
        DESTROY,
        DELCONSUMER,
        MAXLEN,
        GROUP,
        IDLE,
        TIME,
        BLOCK,
        NOACK,
        RETRYCOUNT,
        STREAM,
        GROUPS,
        CONSUMERS,
        JUSTID,
        WITHVALUES,
        NOMKSTREAM,
        MINID,
        CREATECONSUMER,
        SETUSER,
        GETUSER,
        DELUSER,
        WHOAMI,
        USERS,
        CAT,
        GENPASS,
        LOG,
        SAVE,
        DRYRUN,
        COPY,
        AUTH,
        AUTH2,
        NX,
        XX,
        EX,
        PX,
        EXAT,
        PXAT,
        ABSTTL,
        KEEPTTL,
        INCR,
        LT,
        GT,
        CH,
        INFO,
        PAUSE,
        UNPAUSE,
        UNBLOCK,
        REV,
        WITHCOORD,
        WITHDIST,
        WITHHASH,
        ANY,
        FROMMEMBER,
        FROMLONLAT,
        BYRADIUS,
        BYBOX,
        BYLEX,
        BYSCORE,
        STOREDIST,
        TO,
        FORCE,
        TIMEOUT,
        DB,
        UNLOAD,
        ABORT,
        IDX,
        MINMATCHLEN,
        WITHMATCHLEN,
        FULL,
        DELETE,
        LIBRARYNAME,
        WITHCODE,
        DESCRIPTION,
        GETKEYS,
        GETKEYSANDFLAGS,
        DOCS,
        FILTERBY,
        DUMP,
        MODULE,
        ACLCAT,
        PATTERN,
        DOCTOR,
        LATEST,
        HISTORY,
        USAGE,
        SAMPLES,
        PURGE,
        STATS,
        LOADEX,
        CONFIG,
        ARGS,
        RANK,
        NOW,
        VERSION,
        ADDR,
        SKIPME,
        USER,
        LADDR,
        FIELDS,
        CHANNELS,
        NUMPAT,
        NUMSUB,
        SHARDCHANNELS,
        SHARDNUMSUB,
        NOVALUES,
        MAXAGE,
        FXX,
        FNX,
        // Additional cluster keywords
        ADDSLOTS,
        ADDSLOTSRANGE,
        BUMPEPOCH,
        COUNTKEYSINSLOT,
        DELSLOTS,
        DELSLOTSRANGE,
        FAILOVER,
        FLUSHSLOTS,
        FORGET,
        GETKEYSINSLOT,
        KEYSLOT,
        LINKS,
        MEET,
        MYID,
        MYSHARDID,
        NODES,
        REPLICAS,
        REPLICATE,
        SAVECONFIG,
        SETSLOT,
        SLAVES,
        SLOTS;

        private final byte[] raw;

        Keyword() {
            raw = name().getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public byte[] getRaw() {
            return raw.clone(); // ✅ Return defensive copy to prevent external modification
        }
    }

    /** Redis protocol cluster keywords enum. */
    public enum ClusterKeyword implements Rawable {
        MEET,
        RESET,
        INFO,
        FAILOVER,
        SLOTS,
        NODES,
        REPLICAS,
        SLAVES,
        MYID,
        ADDSLOTS,
        DELSLOTS,
        GETKEYSINSLOT,
        SETSLOT,
        NODE,
        MIGRATING,
        IMPORTING,
        STABLE,
        FORGET,
        FLUSHSLOTS,
        KEYSLOT,
        COUNTKEYSINSLOT,
        SAVECONFIG,
        REPLICATE,
        LINKS,
        ADDSLOTSRANGE,
        DELSLOTSRANGE,
        BUMPEPOCH,
        MYSHARDID,
        SHARDS;

        private final byte[] raw;

        ClusterKeyword() {
            raw = name().getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public byte[] getRaw() {
            return raw.clone(); // ✅ Return defensive copy to prevent external modification
        }
    }
}
